package uplift.project.model;

import java.util.ArrayList;

import android.util.Log;

import uplift.project.model.VolunteerEvent;

public class VolunteerEventsList {
	
	public ArrayList<VolunteerEvent> eventsList;
	
	/**
	 * Creates a new list of VolunteerEvent objects.
	 */
	public VolunteerEventsList() {
		eventsList = new ArrayList<VolunteerEvent>();
		
		// Create some default events to pre-populate the list
		VolunteerEvent ve1 = new VolunteerEvent("Feed the Homeless", "Misc", "Seattle, WA", "June 5, 2012",
												"4:00pm", "6:00pm",
												"Come help us feed the homeless in downtown Seattle!",
												false, false);

		VolunteerEvent ve2 = new VolunteerEvent("Canned Food Drive", "Food", "Auburn, WA", "May 27, 2012",
												"10:00am", "5:00pm",
												"Bring us canned foods or non-perishable food items to donate to some organization that feeds people with " +
														"canned foods and non-perishable food items! Monetary donations will also be accepted.",
												false, false);

		VolunteerEvent ve3 = new VolunteerEvent("Bake Sale", "Food", "UWCSE Building", "June 9, 2012",
												"3:00pm", "6:30pm",
												"We are selling cookies, cakes, pies, pastries, and lots of other delicious foods to help raise money for" +
														" Doctors Without Borders. Come buy our sweets! They taste yummy!",
												false, false);
		
		VolunteerEvent ve4 = new VolunteerEvent("Forest Restoration", "Nature", "Imaginary Park", "May 27, 2012",
												"10:00am", "3:00pm",
												"Too many trees are being cut down for housing developments! Let's restore some of our forests by planting " +
														"trees at Imaginary Park!",
												false, false);
		
		VolunteerEvent ve5 = new VolunteerEvent("Youth Camp", "Misc", "Kent, WA", "June 26, 2012",
												"12:00pm", "3:00pm",
												"Come help us bring joy to some of the underprivileged and foster children of Kent! Play basketball, ping " +
														"pong, read books, or do math problems with them!",
												false, false);

		VolunteerEvent ve6 = new VolunteerEvent("Silent Auction", "Misc", "Seattle, WA", "June 12, 2012",
												"2:00pm", "6:30pm",
												"We are holding a silent auction to help raise money for the American Red Cross. Items up for bid include " +
														"video games, sports tickets, and much more.",
												false, false);

		VolunteerEvent ve7 = new VolunteerEvent("Read to Elderly", "Elderly", "Renton Retirement Home", "June 9, 2012",
												"12:00pm", "3:00pm",
												"Our elderly like to stay sharp, so come keep their minds active by reading books to them! Books will be " +
														" provided, as well as a light lunch.",
												false, false);
		
		VolunteerEvent ve8 = new VolunteerEvent("Cat Rescue", "Animals", "Seattle Animal Shelter", "June 8, 2012",
												"10:00am", "5:30pm",
												"We are short on volunteers and need your help! Come help save sick and abused cats. You will be expected to " +
														" feed and play with the cats. Bring your own lunch.",
												false, false);
		
		VolunteerEvent ve9 = new VolunteerEvent("Gaming for Charity", "Misc", "UWCSE Building", "June 16, 2012",
												"5:00pm", "9:30pm",
												"Do you like gaming with other gaming nerds? Well come play XB360, PS3, Wii, and PC games with other nerds " +
												 " to help us raise money for Child's Play! Snacks provided. $10 entry fee.",
												false, false);
		
		VolunteerEvent ve10 = new VolunteerEvent("Blood Donation", "Misc", "Seattle, WA", "June 9, 2012",
												"11:00am", "5:00pm",
												"Come give blood! Your blood can save up to three lives!",
												false, false);
		
		this.addEvent(ve1);
		this.addEvent(ve2);
		this.addEvent(ve3);
		this.addEvent(ve4);
		this.addEvent(ve5);
		this.addEvent(ve6);
		this.addEvent(ve7);
		this.addEvent(ve8);
		this.addEvent(ve9);
		this.addEvent(ve10);
	}
	
	/**
	 * Adds a VolunteerEvent to the list of events.
	 * 
	 * @param ve - The VolunteerEvent to be added
	 * @return Returns a boolean indicating whether or not the add was successful. Returns false
	 *  if the event already exists in the event list. Events are compared for equality by all fields.
	 */
	public boolean addEvent(VolunteerEvent veToAdd) {
		for (VolunteerEvent veInList : eventsList) {
			if (eventsAreEqual(veInList, veToAdd))
				return false;
		}
		eventsList.add(veToAdd);
		return true;
	}
	
	/**
	 * Returns an arraylist of all of the VolunteerEvents the user is currently signed
	 *  up for, excluding events created by the user. This method may be useful for the
	 *  MyEvents page and listing joined events. The reason it doesn't include created
	 *  events is so that events aren't duplicated in the two different lists.
	 *  
	 *  @return ArrayList - List of all VolunteerEvents user is signed up for. This
	 *   excludes events that the user has created.
	 */
	public ArrayList<VolunteerEvent> getJoinedEvents() {
		ArrayList<VolunteerEvent> joinedEvents = new ArrayList<VolunteerEvent>();
		
		for (VolunteerEvent veInList : eventsList) {
			if (veInList.joined() && !veInList.isUserCreated())
				joinedEvents.add(veInList);
		}
		
		return joinedEvents;
	}
	
	/**
	 * Returns an arraylist of all of the VolunteerEvents the user has created and that
	 *  haven't been deleted.
	 *  
	 *  @return ArrayList - List of all VolunteerEvents user has created.
	 */
	public ArrayList<VolunteerEvent> getUserCreatedEvents() {
		ArrayList<VolunteerEvent> userEvents = new ArrayList<VolunteerEvent>();
		
		for (VolunteerEvent veInList : eventsList) {
			if (veInList.isUserCreated())
				userEvents.add(veInList);
		}
		
		return userEvents;
	}
	
	/**
	 * Returns an arraylist of the events that are already in the app. In other words,
	 *  hard-coded events not created by the user to help populate our lists. The list
	 *  returned also filters out joined events.
	 *  
	 *  @return ArrayList - List of VolunteerEvents not created by the user
	 */
	public ArrayList<VolunteerEvent> getDefaultEvents() {
		ArrayList<VolunteerEvent> defaultEvents = new ArrayList<VolunteerEvent>();
		
		for (VolunteerEvent veInList : eventsList) {
			if (!veInList.isUserCreated())
				defaultEvents.add(veInList);
		}
		
		return defaultEvents;
	}
	
	/**
	 * Returns an arraylist of the events that the user has not signed up, and that
	 * 	the user did not create.
	 * 
	 *  @return ArrayList - List of VolunteerEvents not created by the user and not joined
	 *  	by the user
	 */
	public ArrayList<VolunteerEvent> getUnassociatedEvents() {
		ArrayList<VolunteerEvent> unassociatedEvents = new ArrayList<VolunteerEvent>();
		
		for (VolunteerEvent veInList : eventsList) {
			if (!veInList.isUserCreated() && !veInList.joined())
				unassociatedEvents.add(veInList);
		}
		
		return unassociatedEvents;
	}
	
	/**
	 * Returns an arraylist of all of the VolunteerEvents. This includes the default ones
	 *  and the ones created by the user. This may be useful for search and browse functions.
	 *  
	 *  @return ArrayList - List of all VolunteerEvents present in the app
	 */
	public ArrayList<VolunteerEvent> getAllEvents() {
		return eventsList;
	}
	
	/**
	 * Removes a user-created event from the list.
	 *  
	 *  @param all the fields
	 *  @return Returns a boolean indicating whether or not the remove was successful
	 */
	public boolean removeEvent(String n, String c, String l, String d, String st, String et, String desc) {
		for (VolunteerEvent veInList : eventsList) {
			if (veInList.isEqual(n, c, l, d, st, et, desc))
				return eventsList.remove(veInList);
		}
		return false;
	}
	
	/**
	 * Removes a user-created event from the list.
	 *  
	 *  @param VolunteerEvent - the VolunteerEvent to be removed
	 *  @return Returns a boolean indicating whether or not the remove was successful
	 */
	public boolean removeEvent(VolunteerEvent veToRemove) {
		for (VolunteerEvent veInList : eventsList) {
			if (eventsAreEqual(veInList, veToRemove))
				return eventsList.remove(veInList);
		}
		return false;
	}
	
	/**
	 * Unregisters an event in the list
	 *  
	 *  @param fields
	 *  @return Returns a boolean indicating whether or not the remove was successful
	 */
	public void unregisterEvent(String n, String c, String l, String d, String st, String et, String desc) {
		for (VolunteerEvent veInList : eventsList) {
			if (veInList.isEqual(n, c, l, d, st, et, desc))
				veInList.unregister();
		}
	}
	
	/**
	 * Joins an event in the list
	 *  
	 *  @param fields
	 *  @return Returns a boolean indicating whether or not the remove was successful
	 */
	public void joinEvent(String n, String c, String l, String d, String st, String et, String desc) {
		for (VolunteerEvent veInList : eventsList) {
			if (veInList.isEqual(n, c, l, d, st, et, desc))
				veInList.join();
		}
	}
	
	/**
	 * Search for list of events that matches the requirements
	 * 
	 * @param l location
	 * @param d destination
	 * @param st start time
	 * @param et end time
	 * @return
	 */
	public ArrayList<VolunteerEvent> searchEvent(String c, String l, String d, String st, String et) {
		ArrayList<VolunteerEvent> searchResults = new ArrayList<VolunteerEvent>();
		for (VolunteerEvent veInList : eventsList) {
			Log.v("veInList", veInList.toString());
			if (!veInList.isUserCreated() && !veInList.joined() && veInList.matches(c, l, d, st, et)) {
				Log.v("Event added!", veInList.toString());
				searchResults.add(veInList);
			}
		}
		return searchResults;
	}
	
	// Returns whether two events are the same or not based on field comparisons
	private boolean eventsAreEqual(VolunteerEvent ve1, VolunteerEvent ve2) {
		return (ve1.getName().equalsIgnoreCase(ve2.getName())) &&
				(ve1.getCategory().equalsIgnoreCase(ve2.getCategory())) &&
				(ve1.getLocation().equalsIgnoreCase(ve2.getLocation())) &&
				(ve1.getDate().equals(ve2.getDate())) &&
				(ve1.getStartTime().equals(ve2.getStartTime())) &&
				(ve1.getEndTime().equals(ve2.getEndTime())) &&
				(ve1.getDescription().equalsIgnoreCase(ve2.getDescription()));
	}
	

}
